﻿using System;

namespace ProblemsSet
{
    public class Problem_148 : BaseProblem
    {
        public override object GetResult()
        {
            //const int max = 1000000000;
            const int max = 2000;

            //return GetCountForN(4);

            BigInteger sum = 1;
            BigInteger sum2 = 1;

            for (BigInteger n = 1; n < max; n++)
            {
                //if (sum2 != sum)
                //    sum2.ToString();

                //sum2 += GetCountForN(n);
                //sum2 = GetCountAllForN(n);
                

                BigInteger nom = GetCount(n);
                if (nom == 0)
                {
                    sum += n+1;
                    continue;
                }
                sum += 2;
                for (BigInteger k = 1; k < n; k++)
                {
                    BigInteger denom = GetCount(k)+GetCount(n-k);
                    if (nom <= denom)
                        sum++;
                }
            }
            return sum;
        }

        private static BigInteger GetCount(BigInteger value)
        {
            BigInteger all = 0;

            BigInteger start = 7;
            while (start <= value)
            {
                all += value/start;
                start *= 7;
            }
            return all;
        }

        private static BigInteger GetCountForN(BigInteger value)
        {
            if (value == 0)
                return 0;
            if (value < 7)
                return value+1;

            var k = (long)(Math.Log(value.LongValue()) / Math.Log(7));
            var k7 = (long)Math.Pow(7, k);
            
            if (value == k7)
            {
                return 2;
            }
            var i = value  / k7;
            var j = (value % k7)%7;
            return k*(i+1)*(j+1);
        }

        private static BigInteger GetCountAllForN(BigInteger value)
        {
            if (value == 0)
                return 0;
            if (value < 7)
                return value + GetCountForN(value - 1);
            var k = (long)(Math.Log(value.LongValue())/Math.Log(7));
            long k7 = (long)Math.Pow(7, k);
            if (value == k7)
            {
                BigInteger tmp = 28;
                return tmp.Pow(k);
            }
            var i = k7*((value - 1)/k7);
            var j = value/k7;
            return GetCountForN(i)+j*GetCountForN(value-i);
        }

        public override string Problem
        {
            get
            {
                return @"We can easily verify that none of the entries in the first seven rows of Pascal's triangle are divisible by 7:

 	 	 	 	 	 	 1
 	 	 	 	 	 1	 	 1
 	 	 	 	 1	 	 2	 	 1
 	 	 	 1	 	 3	 	 3	 	 1
 	 	 1	 	 4	 	 6	 	 4	 	 1
 	 1	 	 5	 	10	 	10	 	 5	 	 1
1	 	 6	 	15	 	20	 	15	 	 6	 	 1
However, if we check the first one hundred rows, we will find that only 2361 of the 5050 entries are not divisible by 7.

Find the number of entries which are not divisible by 7 in the first one billion (109) rows of Pascal's triangle.";
            }
        }

        public override bool IsSolved
        {
            get
            {
                return false;
            }
        }

        public override object Answer
        {
            get
            {
                return null;
            }
        }

    }
}
